const username = document.getElementById('username')
const shareDesktopBtn = document.getElementById('shareDesktopBtn')
const addBtn = document.getElementById('addBtn')
const localVideo = document.getElementById('localVideo')

const ROOM_NUM = 101

let localStream
let users
let socket
const peers = {}
let pc

const peerOptions = {
    offerToReceiveAudio: false,
    offerToReceiveVideo: true
}

function sendMessage(message, socketId) {
    if (!message) return;
    const user = username.value
    console.log(`${user} send message :`)
    console.log(message);
    socket.emit('message', ROOM_NUM, user, message, socketId);
}

/**
 * 共享桌面方法
 */
function shareDesktop() {
    if (!navigator.mediaDevices || !navigator.mediaDevices.getDisplayMedia) return;
    navigator.mediaDevices.getDisplayMedia().then(stream => {
        localVideo.srcObject = stream
        localStream = stream
    }).catch(err => console.error(err))
    username.value = "HOST"
    initConn()
}



function joinRoom() {
    initConn()
}

function initConn() {
    const user = username.value
    socket = io.connect('https://chris.mynatapp.cc')
    socket.on('joined', (room, socketId, id) => {
        // 建立链接
        if (user === id && id !== "HOST") {
            pc = createPeerConnection(socketId)
            pc.createOffer(peerOptions).then(desc => {
                pc.setLocalDescription(desc)
                sendMessage(desc, users['HOST'])
            }).catch(err => console.error(err))
        }
        if (users) {
            users[id] = socketId
        }
    })

    socket.on('message', (room, id, message) => {
        console.log(`${id} get message :`)
        console.log(message)
        if (message.type === 'offer') {
            const localPc = createPeerConnection(id)
            peers[id] = localPc;
            localPc.setRemoteDescription(new RTCSessionDescription(message))
            localPc.createAnswer(peerOptions).then(desc => {
                localPc.setLocalDescription(desc)
                sendMessage(desc, users[id])
            }).catch(err => console.error(err))
        } else if (message.type === 'answer') {
            pc.setRemoteDescription(new RTCSessionDescription(message))
        } else if (message.type === 'candidate') {
            const candidate = new RTCIceCandidate({
                candidate: message.candidate,
                sdpMLineIndex: message.label
            })
            if (pc && id !== user) {
                pc.addIceCandidate(candidate)
            } else {
                // peers[id].addIceCandidate(candidate)
            }
        } else {

        }
    })

    socket.on('userstatechange', (room, allUser) => {
        if (!users)
            users = allUser
    })

    socket.on('leave', (room, id) => {
        // 关闭其他人资源
        console.log(`${id} leave ${room}`);
    })
    socket.emit('join', ROOM_NUM, user)
}

function createPeerConnection(id) {
    console.log("=========================")
    const pc = new RTCPeerConnection()
    pc.onicecandidate = e => {
        console.log("=================== onicecandidate:");
        console.log(e.candidate);

        if (e.candidate) {
            sendMessage({
                type: 'candidate',
                label: e.candidate.sdpMLineIndex,
                id: e.candidate.sdpMid,
                candidate: e.candidate.candidate
            })
        }
    }
    pc.ontrack = e => {
        console.log("received remote video:");
        console.log(e);
        if (!localStream) {
            localVideo.srcObject = e.streams[0]
        }
    }

    if (localStream) {
        localStream.getTracks().forEach(stream => {
            pc.addTrack(stream, localStream)
        });
    }
    return pc;
}

shareDesktopBtn.onclick = shareDesktop
addBtn.onclick = joinRoom

function leave() {
    if (socket) {
        const user = username.value
        socket.emit('leave', ROOM_NUM, user);
        socket.disconnect()
        socket = null
    }
    if (pc) {
        closePeerConnection(pc)
    }

}

function closePeerConnection(peer) {
    if (!peer) {
        peer.close()
        peer = null
    }
}


window.onbeforeunload = (e) => {
    leave()
    return true
}